package org.theSeed.fileContract.contract.impl;

import cn.hutool.core.util.ObjectUtil;
import org.theSeed.fileContract.contract.UploadFileRecorder;
import org.theSeed.fileContract.exp.FileUploadExp;
import org.theSeed.fileContract.pojo.dto.RecordChipInfoDto;
import org.theSeed.fileContract.pojo.dto.RecordChipUploadInfoDto;
import org.theSeed.fileContract.pojo.dto.RecordFileUniInfoDto;
import org.theSeed.fileContract.utils.SeedFileConfigUtil;

import java.util.*;

/**
 * 单机文件上传记录者
 */
public class UploadFileSingleRecorder implements UploadFileRecorder {
    private Map<Long,String> timeHolder = Collections.synchronizedMap(new LinkedHashMap<>());

    private Map<String, Integer> chipInitInfo = Collections.synchronizedMap(new HashMap<>());

    private Map<String, Set<Integer>> chipInfo = Collections.synchronizedMap(new HashMap<>());

    /**
     * 定时清除相关分片上传信息
     */
    public void startTimeHolder(){
        new Thread(()->{
            long now = System.currentTimeMillis();
            for (Map.Entry<Long, String> longStringEntry : timeHolder.entrySet()) {
                Long key = longStringEntry.getKey();
                String value = longStringEntry.getValue();
                if (now - key > 1000 * 60 * 60 * 24){
                    chipInitInfo.remove(value);
                    chipInfo.remove(value);
                    timeHolder.remove(key);
                }
            }
        }).start();
    }

    @Override
    public void addUploadInfo(RecordFileUniInfoDto recordFileUniInfoDto) {
    }

    @Override
    public void removeUploadInfo(RecordFileUniInfoDto recordFileUniInfoDto) {
    }

    @Override
    public void addChipInfo(RecordChipInfoDto recordChipInfoDto) {
        chipInitInfo.put(SeedFileConfigUtil.createChipKey(recordChipInfoDto.getContractType(),recordChipInfoDto.getContractTypeInstance(),recordChipInfoDto.getResourceId()),recordChipInfoDto.getChipSize());
    }


    @Override
    public void addChipUploadInfo(RecordChipUploadInfoDto recordChipUploadInfoDto) {
        String chipKey = SeedFileConfigUtil.createChipKey(recordChipUploadInfoDto.getContractType(), recordChipUploadInfoDto.getContractTypeInstance(), recordChipUploadInfoDto.getResourceId());
        getChipIndexSet(chipKey).add(recordChipUploadInfoDto.getChipIndex());
    }

    @Override
    public List<Integer> checkChipUploadInfo(RecordFileUniInfoDto recordFileUniInfoDto) {
        List<Integer> res = new ArrayList<>();
        String chipKey = SeedFileConfigUtil.createChipKey(recordFileUniInfoDto.getContractType(), recordFileUniInfoDto.getContractTypeInstance(), recordFileUniInfoDto.getResourceId());
        Integer size = chipInitInfo.get(chipKey);
        Set<Integer> chipIndexSet = getChipIndexSet(chipKey);
        if (ObjectUtil.isNotNull(size) && ObjectUtil.isNotNull(chipIndexSet)){
            if (chipIndexSet.size() != size){
                for (Integer l = 0; l < size; l++) {
                    if (!chipIndexSet.contains(l)){
                        res.add(l);
                    }
                }
            }
            return res;
        }
        throw new FileUploadExp("文件分片校验失败:上传已取消或未初始化");
    }

    @Override
    public void removeChipUploadInfo(RecordFileUniInfoDto recordFileUniInfoDto) {
        String chipKey = SeedFileConfigUtil.createChipKey(recordFileUniInfoDto.getContractType(), recordFileUniInfoDto.getContractTypeInstance(), recordFileUniInfoDto.getResourceId());
        chipInitInfo.remove(chipKey);
        chipInfo.remove(chipKey);
    }

    /**
     * 获取相关上传信息
     * @param chipKey
     * @return
     */
    private synchronized Set<Integer> getChipIndexSet(String chipKey) {
        Integer parent = chipInitInfo.get(chipKey);
        if (ObjectUtil.isNull(parent)){
            throw new FileUploadExp("文件分片校验失败:上传已取消或未初始化");
        }
        Set<Integer> chipIndexSet = chipInfo.get(chipKey);
        if (ObjectUtil.isNull(chipIndexSet)){
            chipIndexSet = Collections.synchronizedSet(new HashSet<>());
        }
        return chipIndexSet;
    }
}
